package com.quanyan.api;/**
 * Created by Administrator on 2016/5/5.
 */

import com.alibaba.fastjson.JSON;
import com.quanyan.entity.Command;
import com.quanyan.entity.DoResultData;
import com.quanyan.entity.ParamStruct;
import com.quanyan.util.ApplicationUtil;
import com.quanyan.util.TypeUtil;
import org.apache.log4j.Logger;
import org.jboss.netty.channel.DefaultChannelFuture;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Method;


/**
 * BusinessCommand
 * description:
 *
 * @author chuntu tuchun168@163.com
 * @date 2016/5/5 18:32
 */
public class BusinessCommand extends AbstractCommand{
    private static final Logger log=Logger.getLogger(AbstractCommand.class);
    public BusinessCommand(ParamStruct paramStruct) {
        super(paramStruct);
    }
    @Override
    protected DoResultData executeCommand() throws Exception {
        DoResultData doResultData=null;

        try {
            Command command = paramStruct.getCommand();
            Object result = null;
            if (command != null) {
                String cmd = command.getCmd();
                String[] params = cmd.split("#");
                //取出命令号
                int cmdNum=Integer.parseInt(params[0]);
                // 取出类路径
                String clazzName = params[1];
                // 取出方法名
                String methodName = params[2];
                // 取出方法的位置 解决方法重构的冲突
                Integer methodPosi = Integer.parseInt(params[3]);

                // 取出数据
                String[] dataArr=null;
                String dataStr = paramStruct.getCommand().getData();
                if(dataStr!=null||!"".equals(dataStr)){
                    dataArr = dataStr.split("#");
                }


                ApplicationContext context=  ApplicationUtil.getInstance();
                DefaultChannelFuture.setUseDeadLockChecker(false);
                Object obj=context.getBean(clazzName);


				/*Object obj = null;
				Constructor<?> constructor = commandHashMap.get(clazzName);
				Class<?> clazz = Class.forName(clazzName);
				if (constructor != null) {
					obj = constructor.newInstance();
				} else {
					constructor = clazz.getDeclaredConstructor();
					commandHashMap.put(clazzName, constructor);
					obj = constructor.newInstance();
				}*/
                Class clazz=obj.getClass();
                Class<?>[] parameterTypes = null;

                int flag = 1;
                Method[] mothodNames = clazz.getMethods();
                for (int i = 0; i < mothodNames.length; i++) {
                    String methodNameR=mothodNames[i].getName();
                    //System.out.println("methodNameR:"+methodNameR);
                    if (methodNameR != null && !"".equals(methodNameR)
                            && methodName.equals(methodNameR)) {
                        if (flag == methodPosi) {//解决方法重构问题
                            parameterTypes = mothodNames[i].getParameterTypes();
                            break;
                        } else {
                            flag++;
                        }
                    }
                }
                //参数数据转换正确格式
                Object[] formatData = TypeUtil.typeTransform(parameterTypes,
                        dataArr,clazzName,methodName);
                Method handleMethod = clazz.getDeclaredMethod(methodName,
                        parameterTypes);

                result = handleMethod.invoke(obj, formatData);

                // 组装返回的结果
                Command commandResult = paramStruct.getCommand();
                log.warn("remotejson:" + JSON.toJSONString(result));
                commandResult.setData(JSON.toJSONString(result));

                doResultData=new DoResultData();
                doResultData.setCommand(commandResult);
            }
            return doResultData;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("执行业务命令异常" + e.getMessage(), e);
            Command commandResult = paramStruct.getCommand();
             commandResult.setData(JSON.toJSONString(e.getMessage()));
            doResultData=new DoResultData();
            doResultData.setCommand(commandResult);
            return doResultData;
        }
     }
}
